package com.khalil.kkadmin.kb.service.impl;

import com.khalil.kkadmin.common.util.CollectionUtils;
import com.khalil.kkadmin.infrastructure.BaseService;
import com.khalil.kkadmin.infrastructure.jpa.domain.EntityBase;
import com.khalil.kkadmin.kb.domain.KbDocument;
import com.khalil.kkadmin.kb.repository.KbDocumentRepository;
import com.khalil.kkadmin.kb.dto.KbDmsDocumentDto;
import com.khalil.kkadmin.kb.service.KbDocumentService;
import com.khalil.kkadmin.system.dms.DmsDocument;
import com.khalil.kkadmin.system.dms.DmsDocumentService;
import com.khalil.kkadmin.system.dms.FileInfo;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class KbDocumentServiceImpl extends BaseService<KbDocumentRepository, KbDocument, Long> implements KbDocumentService {

    @Autowired
    private DmsDocumentService dmsDocumentService;

    public KbDocumentServiceImpl(KbDocumentRepository repository) {
        super(repository);
    }

    private final List<String> UPLOAD_PATH = Arrays.asList("kbdocument");

    @Override
    protected KbDocument str2CreateEntity(String json) {
        return null;
    }

    @Override
    protected KbDocument str2UpdateEntity(String json) {
        return null;
    }

    @Override
    public List<KbDocument> list(String params) {
        return List.of();
    }

    @Override
    public List<KbDmsDocumentDto> upload(Long dirId, List<MultipartFile> files) {
        List<KbDmsDocumentDto> documentInfoList = new ArrayList<>();
        files.forEach(file -> {
            String originalFilename = file.getOriginalFilename();
            String extension = FilenameUtils.getExtension(originalFilename);
            String contentType = file.getContentType();
            InputStream inputStream = null;
            try {
                inputStream = file.getInputStream();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            long fileSize = file.getSize();
            FileInfo fileInfo = FileInfo.builder()
                    .originalFilename(originalFilename)
                    .contentType(contentType)
                    .size(fileSize)
                    .extension(extension)
                    .inputStream(inputStream).build();
            DmsDocument dmsDocument = dmsDocumentService.upload(UPLOAD_PATH, fileInfo);

            KbDocument kbDocument = new KbDocument();
            kbDocument.setDocumentId(dmsDocument.getId());
            kbDocument.setDirId(dirId);
            repository.save(kbDocument);

            KbDmsDocumentDto documentDto = new KbDmsDocumentDto();
            documentDto.setId(kbDocument.getId());
            documentDto.setDocumentId(dmsDocument.getId());
            documentDto.setDirId(dirId);
            BeanUtils.copyProperties(dmsDocument, documentDto);
            documentInfoList.add(documentDto);
        });
        return documentInfoList;
    }

    @Override
    public KbDmsDocumentDto getKbDocument(Long id) {
        Optional<KbDocument> kbDocumentOptional = repository.findById(id);
        if (kbDocumentOptional.isEmpty()) {
            return null;
        }
        KbDocument kbDocument = kbDocumentOptional.get();
        DmsDocument dmsDocument = dmsDocumentService.findById(kbDocument.getDocumentId());
        if (dmsDocument == null) {
            return null;
        }
        return buildKbDmsDocumentDto(kbDocument, dmsDocument);
    }

    @Override
    public List<KbDmsDocumentDto> getKbDocumentList(Long dirId) {
        List<KbDocument> kbDocumentList = repository.findAllByDirId(dirId);
        if (CollectionUtils.isEmpty(kbDocumentList)) {
            return Collections.emptyList();
        }
        List<Long> documentIdList = kbDocumentList.stream().map(KbDocument::getDocumentId).toList();
        List<DmsDocument> dmsDocumentList = dmsDocumentService.findByIdList(documentIdList);
        Map<Long, DmsDocument> documentMap = dmsDocumentList.stream().collect(Collectors.toMap(EntityBase::getId, Function.identity()));

        return kbDocumentList.stream().map(kbDocument -> {
            DmsDocument dmsDocument = documentMap.get(kbDocument.getDocumentId());

            return buildKbDmsDocumentDto(kbDocument, dmsDocument);
        }).collect(Collectors.toList());
    }

    private KbDmsDocumentDto buildKbDmsDocumentDto(KbDocument kbDocument, DmsDocument dmsDocument) {
        KbDmsDocumentDto documentDto = new KbDmsDocumentDto();
        BeanUtils.copyProperties(dmsDocument, documentDto);
        documentDto.setId(kbDocument.getId());
        documentDto.setDocumentId(kbDocument.getDocumentId());
        documentDto.setCreatedAt(kbDocument.getCreatedAt());
        return documentDto;
    }

    @Transactional
    @Override
    public void deleteByIdList(List<Long> idList) {
        for (Long id : idList) {
            deleteById(id);
        }
    }

    @Transactional
    @Override
    public void deleteById(Long id) {
        // 删除文件
        KbDocument kbDocument = repository.findById(id).orElse(null);
        if (kbDocument != null) {
            dmsDocumentService.deleteById(kbDocument.getDocumentId());
        }
        // 删除数据
        repository.deleteById(id);
    }
}
